package com.maxmlr.net.rpc;

import com.google.protobuf.Value;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.List;
import java.util.Objects;

/**
 * @ClassName SerHander
 * @Description TODO
 * @Author maxiao
 * @Date 2020/4/4 下午7:49
 * @Version V1.0
 */
@Getter
@AllArgsConstructor
public class ProcessorHandler implements Runnable {

    private Object service;
    private Socket socket;

    @Override
    public void run() {

        try {
            //（接收客户端的流）
            ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
            Object o = in.readObject();
            //转化为对象
            Object result = invoke((Rpc.RpcRequest) o);

            Value build = Value.newBuilder().setStringValue((String) result).build();

            ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
            out.writeObject(build);
            out.flush();
            out.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
            }
        }

    }

    private Object invoke(Rpc.RpcRequest rpcRequest) throws InvocationTargetException, IllegalAccessException {
        String methodName = rpcRequest.getMethodName();
        List<Value> argsList = rpcRequest.getArgsList();

        Object[] args = new Object[argsList.size()];
        Method[] methods = service.getClass().getMethods();
        Method method = null;
        for (Method method1 : methods) {
            if (Objects.equals(method1.getName(), methodName)) {
                if (method1.getParameterCount() == argsList.size()) {
                    method = method1;
                    break;
                }
            }
        }

        if (Objects.isNull(method)) {
            return null;
        }

        Class<?>[] parameterTypes = method.getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            Class types = parameterTypes[i];
            Value value = argsList.get(i);
            if (types == String.class) {
                args[i] = value.getStringValue();
            } else if (types == Integer.class || types == Long.class) {
                args[i] = new Double(value.getNumberValue()).intValue();
            } else {
                args[i] = value.getStringValue();
            }
        }
        System.out.println("aaaa");

        return method.invoke(service, args);
    }
}
